package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/e421083458/gorm"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/gogf/gf/util/gconv"
	"rock/customer/dto"
	"rock/customer/initParam"
	"rock/customer/models"
	"rock/customer/modules/redisModules"
	"rock/customer/public"
	"time"
)

type CustomerService struct {
}

// 用户 - 客服
func (cs *CustomerService) CsUserByUnionId(c *gin.Context, tx *gorm.DB, unionId string) (data dto.UserDetail, err error) {
	//
	common := &Common{}
	userId := common.UnionIdToUserId(c, tx, unionId)
	if userId == "" {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	return cs.CsUser(c, tx, gconv.Int(userId))
}

// 用户 - 客服
func (cs *CustomerService) CsUser(c *gin.Context, tx *gorm.DB, userId int) (data dto.UserDetail, err error) {
	// 取缓存
	redisData := dto.UserDetail{}
	redisCache := redisModules.ClientRedis.Get(initParam.CsUserPrefix + gconv.String(userId))
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &redisData)
		if err != nil {
			return redisData, err
		}
		return redisData, err
	} else {
		if err != redis.Nil {
			return data, err
		}
	}
	// 查db
	err = tx.SetCtx(public.GetGinTraceContext(c)).
		Model(&models.WkbUsers{}).
		Table("wkb_users wu").
		Select("wu.id as uid,wra.tel as mobile,wcs.nickname as realname,"+
			"wcs.nickname,wra.company_address as co,wra.email,wra.usertype as user_type,"+
			"wcs.is_online,wud.autograph,wud.introduce,wud.im_user_type,wu.wechat_openid,"+
			"wcs.is_manage,wcs.see_customer_service,wcs.see_customer,wud.avatar").
		Joins("inner join wkb_user_detail wud on wud.uid = wu.id").
		Joins("inner join wkb_im_customer_service wcs on wcs.uid = wu.id").
		Joins("inner join wkb_realname_auth wra on wra.uid = wu.id").
		Where("wu.id = ? and wcs.deleted = 2", userId).
		Scan(&data).Error
	if err != nil {
		if err.Error() != gorm.ErrRecordNotFound.Error() {
			err = errors.New(initParam.DataIsNotExist)
			return
		}
	}
	if data.UserId == 0 {
		err = errors.New(initParam.DataIsNotExist)
		return
	}
	// 存缓存
	err = addRedis(data, initParam.CsUserPrefix + gconv.String(userId), 3*24*time.Hour)
	return
}

// 用户 - 所有客服
func (cs *CustomerService) CsUserAll(c *gin.Context, tx *gorm.DB) (userDetailOutput []dto.UserDetail, err error) {
	err = tx.SetCtx(public.GetGinTraceContext(c)).
		Model(&models.WkbImCustomerService{}).
		Group("uid").
		Scan(&userDetailOutput).Error
	return
}

// 用户 - 客服 - 更新接待数
func (cs *CustomerService) UpdateCsUserReceptionNum(gc *gin.Context, tx *gorm.DB, userId int, skillGroupId int) error {
	imCustomerServiceGroup := &models.WkbImCustomerServiceGroup{}
	if skillGroupId != 0 {
		err := tx.SetCtx(public.GetGinTraceContext(gc)).Model(imCustomerServiceGroup).
			Where("uid = ? and group_id = ? and deleted = 2", userId, skillGroupId).
			Update("reception_num", gorm.Expr("reception_num + ?", 1)).Error
		if err != nil {
			return err
		}
	}
	imCustomerService := &models.WkbImCustomerService{}
	err := tx.SetCtx(public.GetGinTraceContext(gc)).Model(imCustomerService).
		Where("uid = ? and deleted = 2", userId).
		Update("reception_num", gorm.Expr("reception_num + ?", 1)).Error
	return err
}

// 用户 - 客服 - 更新在线状态
func (cs *CustomerService) UpdateCsUserOnline(gc *gin.Context, tx *gorm.DB, userId string, onlineStatus int) error {
	param := make(map[string]interface{}, 0)
	param["is_online"] = onlineStatus
	return tx.SetCtx(public.GetGinTraceContext(gc)).Model(models.WkbImCustomerService{}).Where("uid = ?", userId).Updates(param).Error
}

// 用户 - 客服 - 客服所在群组
func (cs *CustomerService) CsUserGroup(gc *gin.Context, tx *gorm.DB, uid string) (data []models.WkbImCustomerServiceGroup, err error) {
	//
	redisCache := redisModules.ClientRedis.Get(initParam.CsUserGroupPrefix + uid)
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	//
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbImCustomerService{}).
		Table("wkb_im_customer_service_group").
		Select("group_id").
		Where("uid = ? and deleted = 2", uid).
		Group("group_id").
		Scan(&data).Error
	//
	err = addRedis(data, initParam.CsUserGroupPrefix + uid, 3*24*time.Hour)
	return
}

// 用户 - 客服 - 通讯录
func (cs *CustomerService) AddrBookList(gc *gin.Context, tx *gorm.DB, pageNum int, pageSize int, uid string, search string, seeCustomerService int, imCustomerServiceGroupStr string, accessType int) (data []dto.AddrBook, count int, err error) {
	if search == "" && seeCustomerService == 3 {
		val := ""
		//accessType 接入模式：0 无；1 转发；2 转接；
		redisCache := redisModules.ClientRedis.Get(initParam.CsUserListPrefix + uid + gconv.String(accessType))
		val, err = redisCache.Result()
		if err == nil {
			err = json.Unmarshal([]byte(val), &data)
			if err != nil {
				count = 0
				return
			}
			count = len(data)
			return
		} else {
			if err != redis.Nil {
				return
			}
		}
	}
	where := ""
	if search != "" {
		where = fmt.Sprintf(" AND ( z.group_name LIKE '%s' OR r.nickname LIKE '%s') ", "%"+search+"%", "%"+search+"%")
	}
	if accessType == 2 {
		where = where + " AND r.is_manage = 1 "
	} else {
		switch seeCustomerService {
		case 1:
			where = where + " AND r.is_manage = 1 "
			if imCustomerServiceGroupStr != "" {
				where = where + " AND gl.group_id in (" + imCustomerServiceGroupStr + ") "
			}
			break
		case 2:
			//where = where + " AND r.is_manage = 2 AND gl.group_id in (" + imCustomerServiceGroupStr + ") "
			where = where + " AND r.is_manage = 2 "
			if imCustomerServiceGroupStr != "" {
				where = where + " AND gl.group_id in (" + imCustomerServiceGroupStr + ") "
			}
			break
		case 3:
			break
		default:
			break
		}
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbImCustomerService{}).
		Table("wkb_im_customer_service_group gl").
		Select("count(*)").
		Joins("INNER JOIN wkb_im_customer_service r ON r.uid = gl.uid "+
			"INNER JOIN wkb_im_skill_group z ON z.id = gl.group_id "+
			"INNER JOIN wkb_user_detail u ON u.uid = r.uid ").
		Where("gl.uid <> ? and gl.deleted = 2 and z.is_show = 1 and r.deleted = 2 "+where, uid).Group("gl.group_id,gl.uid").Count(&count).Error
	if count == 0 {
		return
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).
		Model(&models.WkbImCustomerService{}).
		Table("wkb_im_customer_service_group gl").
		Select("gl.group_id,z.group_name,u.uid as user_id,r.nickname as real_name,u.avatar,r.is_online").
		Joins("INNER JOIN wkb_im_customer_service r ON r.uid = gl.uid "+
			"INNER JOIN wkb_user_detail u ON u.uid = r.uid "+
			"INNER JOIN wkb_im_skill_group z ON z.id = gl.group_id").
		Where("gl.uid <> ? and gl.deleted = 2 and z.is_show = 1 and r.deleted = 2 "+where, uid).
		Group("gl.group_id,gl.uid").
		Order("gl.group_id ASC").
		//Limit(pageSize).Offset((pageNum-1)*pageSize).
		Scan(&data).Error
	// 存缓存
	if search == "" && seeCustomerService == 3 {
		err = addRedis(data, initParam.CsUserListPrefix + uid + gconv.String(accessType), 3*24*time.Hour)
	}
	return
}

// 用户 - 客服 - 注册信息
func (cs *CustomerService) CsUserRegister(gc *gin.Context, tx *gorm.DB, mobile string) (data models.WkbImCustomerServiceRegister, err error) {
	// 取缓存
	redisCache := redisModules.ClientRedis.Get(initParam.CsUserRegisterPrefix + gconv.String(mobile))
	val, err := redisCache.Result()
	if err == nil {
		err = json.Unmarshal([]byte(val), &data)
		if err != nil {
			return
		}
		return
	} else {
		if err != redis.Nil {
			return
		}
	}
	return
}

// 用户 - 客服 - 创建注册信息
func (cs *CustomerService) CreateCsUserRegister(gc *gin.Context, tx *gorm.DB, userId int, mobile string) error {
	err := tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbUserDetail{}).Where("uid = ?", userId).Update("mobile", mobile).Error
	if err != nil {
		return err
	}
	data := models.WkbImCustomerServiceRegister{
		UserId: userId,
		Mobile: mobile,
	}
	err = tx.SetCtx(public.GetGinTraceContext(gc)).Model(&models.WkbImCustomerServiceRegister{}).Create(&data).Error
	//添加缓存
	err = addRedis(data, initParam.CsUserRegisterPrefix + gconv.String(mobile), 7*24*time.Hour)
	return err
}
